package algoU2A3;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;

public class U2A3 extends Frame {

	Shuffle s;
	Vector<Image> slides;

	public static void main(String[] args) throws IOException {

		Vector<Image> mySlides = new Vector<Image>();
		
		String userHomeDir = System.getProperty("user.home",".");
		String systemDir = userHomeDir + "/.collection";
		String fileLocation = systemDir + "/file.txt";
		
		mySlides.add(ImageIO.read(new File("C:/Users/Andreas/workspace/Algorithmen und Datenstrukturen/src/algoU2A3/bush34_119.jpg")));
		mySlides.add(ImageIO.read(new File("C:/Users/Andreas/workspace/Algorithmen und Datenstrukturen/src/algoU2A3/image-516473-galleryV9-jtho.jpg")));
		mySlides.add(ImageIO.read(new File("C:/Users/Andreas/workspace/Algorithmen und Datenstrukturen/src/algoU2A3/IMG_20130310_230627.jpg")));
		mySlides.add(ImageIO.read(new File("C:/Users/Andreas/workspace/Algorithmen und Datenstrukturen/src/algoU2A3/pony.png")));
		mySlides.add(ImageIO.read(new File("C:/Users/Andreas/workspace/Algorithmen und Datenstrukturen/src/algoU2A3/krill.jpg")));
		
//		mySlides.add(Toolkit.getDefaultToolkit().getImage("bush34_119.jpg"));
//		mySlides.add(Toolkit.getDefaultToolkit().getImage("image-516473-galleryV9-jtho.jpg"));	
//		mySlides.add(Toolkit.getDefaultToolkit().getImage("IMG_20130310_230627.jpg"));
//		mySlides.add(Toolkit.getDefaultToolkit().getImage("LiquoriceAllsorts2003.jpg"));
//		mySlides.add(Toolkit.getDefaultToolkit().getImage( "krill.gif" ));
//		mySlides.add(Toolkit.getDefaultToolkit().getImage("pony.png"));

		new U2A3(mySlides);
	}

	U2A3(Vector<Image> args) {
		slides=args;
		setLayout(new BorderLayout());
		add(s = new Shuffle(args), BorderLayout.CENTER);
		pack();
		setVisible(true);
	}

	class Shuffle extends Component implements Runnable {
		final int W = 500;
		final int H = 300;
		
		Image m_Img1, m_Img2, m_Img;
		MemoryImageSource m_ImgSrc;
		int[] m_Img1Pix = new int[W * H];
		int[] m_Img2Pix = new int[W * H];
		int[] m_Pix = new int[W * H];

		Shuffle(Vector<Image> imagesToShuffle) {
			slides = imagesToShuffle;
			Thread t = new Thread(this);
			t.start();
		}

		void initSlides(int slidePosition1, int slidePosition2) {
			m_Img1 = slides.get(slidePosition1).getScaledInstance(W, H,
					Image.SCALE_SMOOTH);
			m_Img2 = slides.get(slidePosition2).getScaledInstance(W, H,
					Image.SCALE_SMOOTH);
			MediaTracker mt = new MediaTracker(this);
			mt.addImage(m_Img1, 0);
			mt.addImage(m_Img2, 0);
			try {
				mt.waitForAll();
			} catch (InterruptedException e) {
			}
			PixelGrabber grab1 = new PixelGrabber(m_Img1, 0, 0, W, H,
					m_Img1Pix, 0, W);
			PixelGrabber grab2 = new PixelGrabber(m_Img2, 0, 0, W, H,
					m_Img2Pix, 0, W);
			try {
				grab1.grabPixels();
			} catch (InterruptedException e) {
			}
			try {
				grab2.grabPixels();
			} catch (InterruptedException e) {
			}
			m_ImgSrc = new MemoryImageSource(W, H, m_Pix, 0, W);
			m_Img = createImage(m_ImgSrc);
		}

		public void paint(Graphics g) {
			g.drawImage(m_Img, 0, 0, this);
		}

		void shuffle(int p) {
			for (int i = 0; i < W * H; ++i) {
				m_Pix[i] = compPix(m_Img1Pix[i], m_Img2Pix[i], p);
			}
			m_Img.flush();
			repaint();
		}

		private int compColor(int x1, int x2, int p) {
			return x1 + (x2 - x1) * p / 100;
		}

		private int compPix(int pix1, int pix2, int p) {
			final int RED = compColor((pix1 >> 16) & 0xff, (pix2 >> 16) & 0xff,
					p);
			final int GREEN = compColor((pix1 >> 8) & 0xff, (pix2 >> 8) & 0xff,
					p);
			final int BLUE = compColor(pix1 & 0xff, pix2 & 0xff, p);
			return 0xff000000 | (RED << 16) | (GREEN << 8) | BLUE;
		}

		@Override
		public void run() {
			while (true) {
				for (int j = 0; j < slides.size() - 2; ++j) {
					initSlides(j, j + 1);
					for (int i = 0; i <= 100; i += 2) {
						s.shuffle(i);
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
						}
					}
				}
				initSlides(slides.size() - 1, 0);
				for (int i = 0; i <= 100; i += 2) {
					s.shuffle(i);
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
					}
				}
			}
		}

		public Dimension getPreferredSize() {
			return getMinimumSize();
		}

		public Dimension getMinimumSize() {
			return new Dimension(W, H);
		}
	}

	public void update(Graphics g) {
		paint(g);
	}
}
